package com.freeter.modules.wiztalk.service.impl;

import com.baomidou.mybatisplus.mapper.EntityWrapper;
import com.baomidou.mybatisplus.mapper.Wrapper;
import com.baomidou.mybatisplus.plugins.Page;
import com.baomidou.mybatisplus.service.impl.ServiceImpl;
import com.freeter.common.utils.DateUtils;
import com.freeter.common.utils.PageUtils;
import com.freeter.common.utils.Query;
import com.freeter.common.utils.RedisUtils;
import com.freeter.modules.wiztalk.dao.ReportTrackDao;
import com.freeter.modules.wiztalk.entity.InfModuleEntity;
import com.freeter.modules.wiztalk.entity.ReportTrackEntity;
import com.freeter.modules.wiztalk.entity.view.ReportTrackView;
import com.freeter.modules.wiztalk.entity.vo.ReportTrackVO;
import com.freeter.modules.wiztalk.service.InfModuleService;
import com.freeter.modules.wiztalk.service.ReportTrackService;
import com.freeter.modules.wiztalk.service.StatisEventService;
import com.freeter.modules.wiztalk.service.StatisModuleService;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.EnableScheduling;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;


@Service("reportTrackService")
@EnableScheduling
public class ReportTrackServiceImpl extends ServiceImpl<ReportTrackDao, ReportTrackEntity> implements ReportTrackService {
    @Autowired
    private RedisUtils redisUtils;

    @Autowired
    private StatisModuleService statisModuleService;

    @Autowired
    private InfModuleService infModuleService;

    @Autowired
    private StatisEventService statisEventService;

    @Override
    public PageUtils queryPage(Map<String, Object> params) {
        Page<ReportTrackEntity> page = this.selectPage(
                new Query<ReportTrackEntity>(params).getPage(),
                new EntityWrapper<ReportTrackEntity>()
        );

        return new PageUtils(page);
    }

    @Override
    public PageUtils queryPage(Map<String, Object> params, Wrapper<ReportTrackEntity> wrapper) {
        Page<ReportTrackView> page = new Query<ReportTrackView>(params).getPage();
        page.setRecords(baseMapper.selectListView(page, wrapper));
        PageUtils pageUtil = new PageUtils(page);
        return pageUtil;

    }

    @Override
    public List<ReportTrackVO> selectListVO(Wrapper<ReportTrackEntity> wrapper) {
        return baseMapper.selectListVO(wrapper);
    }

    @Override
    public ReportTrackVO selectVO(Wrapper<ReportTrackEntity> wrapper) {
        return baseMapper.selectVO(wrapper);
    }

    @Override
    public List<ReportTrackView> selectListView(Wrapper<ReportTrackEntity> wrapper) {
        return baseMapper.selectListView(wrapper);
    }

    @Override
    public ReportTrackView selectView(Wrapper<ReportTrackEntity> wrapper) {
        return baseMapper.selectView(wrapper);
    }


    /**
     * 将实时表中的埋点信息，迁移到历史表中
     */
    @Override
    @Scheduled(cron = "0 0 3 * * * ")
    @Transactional
    public void transferReportTrack() {
        Map<String, Object> params = new HashMap<String, Object>();
        params.put("endTime", DateUtils.getYesterDayBegin());
        List<ReportTrackEntity> entityList = baseMapper.selectListEntity(params, "wztk_report_track");
        if (!entityList.isEmpty()) {
            baseMapper.batchInsert(entityList, "wztk_report_track_history");
            baseMapper.batchDelete(entityList, "wztk_report_track");
        }
    }

    /**
     * 统计昨天的页面访问情况，并入库
     */
    @Override
    @Scheduled(cron = "0 0 1 * * * ")
    @Transactional
    public void statModuleYesterday() {
        Date date = DateUtils.addDateDays(new Date(), -1);
        String yesterday = DateUtils.format(date);
        List<Map<String, Object>> entityList = statModuleByDay(yesterday);
        if (!entityList.isEmpty()) {
            statisModuleService.batchInsert(entityList);
        }
    }


    /**
     * 统计昨天的自定义事件消息的数量，并入库
     */
    @Override
    @Scheduled(cron = "0 0 2 * * * ")
    @Transactional
    public void statEventYesterday() {
        Date date = DateUtils.addDateDays(new Date(), -1);
        String yesterday = DateUtils.format(date);
        List<Map<String, Object>> entityList = statEventByDay(yesterday);
        if (!entityList.isEmpty()) {
            statisEventService.batchInsert(entityList);
        }
    }

    /**
     * 根据日期来统计页面被访问的情况
     *
     * @param day
     * @return
     */
    public List<Map<String, Object>> statModuleByDay(String day) {
        return baseMapper.statModuleByDay(day);
    }

    /**
     * 根据日期来统计自定义事件的消息数量
     *
     * @param day
     * @return
     */
    public List<Map<String, Object>> statEventByDay(String day) {
        return baseMapper.statEventByDay(day);
    }

    /**
     * 获取当前的页面访问的统计结果
     */
    @Override
    public List<Map<String, Object>> getModuleStatNow(String appId) {
        List<Map<String, Object>> statNow = baseMapper.getModuleStatNow(appId);
        double sum = 0;
        for (Map<String, Object> map : statNow) {
            sum = sum + ((BigDecimal) map.get("num")).doubleValue();
        }
        for (Map<String, Object> map : statNow) {
            map.put("percentage", (((BigDecimal) map.get("num")).doubleValue() / sum));
        }
        return statNow;
    }

    /**
     * 导入新页面
     */
    @Override
    public void importModules() {
        List<Map<String, Object>> newModules = baseMapper.selectNewModules();
        List<InfModuleEntity> moduleList = infModuleService.importModules(newModules);
        redisUtils.importModules(moduleList);
        for (InfModuleEntity module : moduleList) {
            baseMapper.coverModuleId(module);
        }
    }

    /**
     * 根据前台传来的条件获取昨天和今天的自定义事件的消息数
     *
     * @param params 前台传递的参数
     * @return
     */
    @Override
    public PageUtils getEventStatTwoDay(Map<String, Object> params) {
        Date date = new Date();
        String today = DateUtils.format(date);
        date = DateUtils.addDateDays(date, -1);
        String yesterday = DateUtils.format(date);
        params.put("today", today);
        params.put("yesterday", yesterday);
        Page page = getEventStatPage(params);
        page.setRecords(baseMapper.getEventStatTwoDay(page, params));
        PageUtils pageUtil = new PageUtils(page);
        return pageUtil;
    }

    /**
     * 根据前台传来的条件设置一个page对象
     *
     * @param params 前台传来的条件
     * @return
     */
    public Page<Map<String, Object>> getEventStatPage(Map<String, Object> params) {
        int pageNum = 1;
        int pageSize = 10;
        if (params.get("page") != null) {
            pageNum = Integer.parseInt(params.get("page").toString());
            if (pageNum <= 0) {
                pageNum = 1;
            }
        }
        if (params.get("limit") != null) {
            pageSize = Integer.parseInt(params.get("limit").toString());
            if (pageSize <= 0) {
                pageSize = 10;
            }
        }
        Page<Map<String, Object>> page = new Page<Map<String, Object>>(pageNum, pageSize);
        if (params.get("sidx") != null) {
            page.setOrderByField(params.get("sidx").toString());
            if (params.get("order") != null) {
                if ("asc".equalsIgnoreCase(params.get("order").toString())) {
                    page.setAsc(true);
                } else if ("desc".equalsIgnoreCase(params.get("order").toString())) {
                    page.setAsc(false);
                }
            }
        }
        return page;
    }

    /**
     * 自定义事件统计详细
     * @param params
     * @return
     */
    @Override
    public List<Map<String, Object>> getEventStatDetail(Map<String, Object> params) {
        Date date =new Date();
        String today = DateUtils.format( new Date());
        String versions=params.get("appVersion") == null ? "":params.get("appVersion").toString();
        if(StringUtils.isNotBlank(versions)){
            versions = formatAppVersion(versions);
            params.put("appVersion",versions);
        }
        if(today.equalsIgnoreCase(params.get("endTime").toString())){
            //今天的实时统计，并查询结果表组合到一起
            date = DateUtils.addDateDays(date, -1);
            params.put("endTime", DateUtils.format(date));
            params.put("today",today);
        }
        List<Map<String,Object>> list =baseMapper.getEventStatDetail(params);
        for(Map<String,Object> map:list){
            map.put("time",map.get("time").toString());//这里要传化一下，因为这个集合从后台传到前端的时候可能会把时间字符串变成时间戳，所以这里再强制转换一下
        }
        return list;
    }


    public String formatAppVersion(String versions){
        if(versions.contains(",")){
            String[] versionArray=versions.split(",");
            StringBuffer stringBuffer = new StringBuffer("");
            for(int i=0;i<versionArray.length;i++){
                    stringBuffer.append("'");
                    stringBuffer.append(versionArray[i]);
                    stringBuffer.append("'");
                    if(i != versionArray.length-1){
                        stringBuffer.append(",");
                    }
            }
            return stringBuffer.toString();
        }else{
            return "'"+versions+"'";
        }
    }


    @Override
    @Scheduled(cron = "0 47 19 * * * ")
    public void test(){
           Map<String,Object> params = new HashMap<String,Object>();
           params.put("appId","10000000001");
           params.put("appVersion","3.1.0");
           params.put("eventId","1");
           params.put("beginTime","2018-09-01");
           params.put("endTime","2018-09-18");
           getEventStatDetail(params);
    }

}
